package org.ricks.ioc;

import org.ricks.agent.Agent;
import org.ricks.agent.DataAgent;
import org.ricks.agent.FileWatcher;
import org.ricks.agent.JavaAgent;
import org.ricks.common.conf.NetWorkConfig;
import org.ricks.dispatch.DispatchManager;
import org.ricks.ioc.bean.factory.AbstractBeanFactory;
import org.ricks.utils.DateUtil;

import java.lang.annotation.Annotation;
import java.util.List;

/**
 * @author chenwei
 * @Description: 注解方式启动server 弊端 只能启动一个服务，但是项目需求可能启动多个server
 * 2022年12月2日 18:37:31 后面找时间这部分进行优化
 * @date 2020/7/914:12
 */
public class AppContext {

    private static App app;

    private static final Banner DEFAULT_BANNER = new DefaultBanner();

    private static Banner.Mode bannerMode = Banner.Mode.ON;

    /**
     * 仅仅是简单的容器启动, server如果需要启动则写代码
     * 启动容器，默认初始化分发器
     * @param source
     * @return
     */
    public static App run(Class source) {
        long start_app = DateUtil.current();
        try {
            Agent agent = (Agent) source.getAnnotation(Agent.class);
            if(agent != null && agent.classLoad()) {
                JavaAgent javaAgent = new JavaAgent();
                FileWatcher fileWatcher = new FileWatcher("classes/ricks/",javaAgent);
                fileWatcher.watch();
            }
            if(agent != null && agent.dataLoad()) {
                DataAgent dataAgent = new DataAgent();
                FileWatcher fileWatcher = new FileWatcher("",dataAgent);
                fileWatcher.watch();
            }
            app = new ClassPathAppContext(source.getPackageName());
            DispatchManager.init(); //初始化网络消息分发器
            if(AppContext.bannerMode == Banner.Mode.ON) DEFAULT_BANNER.printBanner();
        } finally {
            long end_app = DateUtil.current();
            System.out.println("============ app started on port:"+ NetWorkConfig.getPort() + " and time:"+ (end_app -start_app) + " ms ===========");
        }
        return app;
    }


    public static AbstractBeanFactory getBeanFactory() {
        if(app != null) {
            return app.getBeanFactory();
        } else {
            throw new RuntimeException("【spring not start........】");
        }
    }

    public static void setBannerMode(Banner.Mode bannerMode) {
        AppContext.bannerMode = bannerMode;
    }

    public static App getApplication() {
        return app;
    }

    public static <T> T getBean(Class<T> type) {
        return app.getBean(type);
    }

    public static List<Object> getBeans() {
        return app.getBeans();
    }

}
